崩潰之後面對的是遲鈍
上一章我們解決了網頁崩潰問題,接下來發現網頁中的動畫在電腦上順利執行,IPhone上執行起來有點鈍,而在部分入門型Android上非常Lag,接下來讓我們找看看問題發生的原因吧
比較運行耗能
我們這次透過 Google Chrome 的 Performance Monitor查看動畫運行時的CPU狀況
動畫準備播放時(左邊電腦MacBook Pro, 右邊小米s4)
電腦也大概2%, 手機約在15%~25%
動畫開始播放(左邊電腦MacBook Pro, 右邊小米s4)
電腦也大概15%~35%, 手機約在90%~100% 瘋狂Lag
由此可知動畫耗能過高,電腦其實已經不太正常,但開發用的電腦配備較高所以運作起來順暢
這個問題在開發電腦版網頁時一直沒發現,直到現在運行在手機上,問題就爆出來了~
尋找效能消耗點
接下來我們透過Google Chrome Performance 錄製了一段耗能狀況
在觀察FPS較低與CPU使用率較高的片段中發現
原來效能大部分耗費在計算畫面更新上
尋找問題得根本
經過測試與尋找,終於找到高耗能的主要問題在這段程式
<style>
.effect.is-play {
animation: effect-keyframes 6.1s step-end infinite paused;
animation-play-state: running;
}
@keyframes effect-keyframes {
0%
background-position-y: 0px;
5%
background-position-y: 422px;
.......
}
</style>
問題其實就出在animation的過程中, 我們變更了background-position-y的位置
詳細原因可查看Google Developers
下面簡單說明一下
Animations And Performance
瀏覽器佈局的流程大概是這樣變更JavaScript/CSS => 計算樣式(style) => 佈局(Layout) => 繪製(Paint) => 渲染層合併(Composite)
當你變更一個屬性(例如: height, width, background-position-y)觸發Layout時,瀏覽器會檢查哪些元素需要重新佈局,然後對整個頁面發送一個reflow(重排), 並完成重新佈局
reflow引發重繪,這對於Web的效能影響是極大的
但如果你修改一個DOM元素的“Paint Only”屬性(例如:opacity, transform),此屬性不影響佈局,因此只會觸發Repaint的流程,變更本身,然後合併渲染變更JavaScript/CSS => 計算樣式(style) => 繪製(Paint) => 渲染層合併(Composite)
只觸發Repaint 對效能有極大幫助
解決方法
現在知道問題了,keyframes在動畫過程中,不斷改變background-position-y,整個畫面不停reflow,導致手機的CPU被吃光光,為解決效能問題,下一章節將使用transform取代background-position-y, top, left等等,與使用 opacity來取代display:none
補充知識點
你知道哪些屬性是Paint Only嗎?
而同一個屬性,在各瀏覽器核心的行為實際上還不一樣喔
可透過以下網址查看你的屬性是那種
CSS Triggers